package drds.plus.executor.cursor.cursor;


import drds.plus.executor.cursor.cursor.impl.DuplicateValueRowDataLinkedList;
import drds.plus.executor.record_codec.record.KeyValueRecordPair;
import drds.plus.executor.record_codec.record.Record;
import drds.plus.executor.row_values.RowValues;
import drds.plus.sql_process.abstract_syntax_tree.configuration.ColumnMetaData;

import java.util.List;
import java.util.Map;

public interface Cursor {
    /**
     * 获取该cursor返回的所有列
     */
    List<ColumnMetaData> getColumnMetaDataList();

    /**
     * 用于判断数据是否已经准备好了。 刚结束查询的时候，这个值是false .直到有数据返回后，这个值会变为true.
     * 并且只要变为true,就不再会回归到false的状态
     */
    boolean isDone();

    /**
     * <pre>
     * 更新操作
     * </pre>
     */
    /**
     * 添加
     */
    void put(Record key, Record value);

    /**
     * 删除 如果当前游标有数据，那么删除这个游标所指向的数据
     */
    boolean delete();

    /**
     * 关闭结果集游标
     */
    List<RuntimeException> close(List<RuntimeException> exceptions);
    //

    /**
     * 结果集的第一行之前的游标位置
     */
    void beforeFirst();

    /**
     * 结果集的第一行的游标位置
     * <readPriority>
     * 也会让[current数据]指向当前值。比如next() 返回的是 1->0 那么再次调用current ，返回的也将是1->0
     * </readPriority>
     */
    RowValues first();

    /**
     * 上一行的游标位置
     * <p>
     * 从实现来说，如果游标未初始化，那么初始化游标并将他放置在结果集的最底端位置上
     * </readPriority>
     * <readPriority>
     * 如果当前映射中有重复的key的数据（比如索引，一个用户有多个商品），那么会导致指针下移，但value可能会变更 如 map : 1->0 ; 1->1 ;
     * 1->2 ; 1->3 那么next会便利所有的1对应的数据，依次返回1->3, 1->2,1->1,1->0
     * </readPriority>
     * <readPriority>
     * prev也会让[current数据]指向当前值。比如next() 返回的是 1->0 那么再次调用current ，返回的也将是1->0
     * </readPriority>
     */
    RowValues prev();

    /**
     * 当前行的游标位置
     */
    RowValues current();


    /**
     * 下一行的游标位置
     * <p>
     * 从实现来说，如果游标未初始化，那么初始化游标并将他放置在结果集的第一个位置上
     * </readPriority>
     * <readPriority>
     * 如果当前映射中有重复的key的数据（比如索引，一个用户有多个商品），那么会导致指针下移，但value可能会变更 如 map : 1->0 ; 1->1 ;
     * 1->2 ; 1->3 那么next会便利所有的1对应的数据，依次返回1->0, 1->1,1->2,1->3
     * </readPriority>
     * <readPriority>
     * next也会让[current数据]指向当前值。比如next() 返回的是 1->0 那么再次调用current ，返回的也将是1->0
     * </readPriority>
     */
    RowValues next();

    /**
     * 游标指向结果集的最后一行的游标位置 也会让[current数据]指向当前值。比如next() 返回的是 1->0 那么再次调用current
     * ，返回的也将是1->0
     */
    RowValues last() throws RuntimeException;

    /**
     * <pre>
     * 快速处理
     * </pre>
     */
    /**
     * 根据指定的key跳到指定的游标位置 如果发现匹配数据，则返回true; 否则返回false 指针跳过去的同时，current对象也进行更新。
     */
    boolean skipTo(Record keyRecord) throws RuntimeException;

    /**
     * 根据指定的key+val跳到指定的游标位置 这个skipto ，要根据KVPair里面的key和val进行查找，同时匹配的时候，才会返回true.
     * 否则返回false 指针跳过去的同时，current对象也进行更新。 随机读
     */
    boolean skipTo(KeyValueRecordPair keyKeyValueRecordPair) throws RuntimeException;

    /**
     * <pre>
     * 重复值处理
     * </pre>
     */
    /**
     * 获取一个相同的值。 如果下一个值为不同值，则返回空 也会让[current数据]指向当前值。比如next() 返回的是 1->0
     * 那么再次调用current ，返回的也将是1->0 简单来说 你在指针跳转的时候，只会利用key跳到值的第一个上。 比如 [0->0, 0->1 ,
     * 0->2,1->0,1->1] 如果skipTo 0，那么指针只会在0->0这里 但第一个值之后，可能有重复的啊。 为了取尽0->0,0->1,0->2
     * 就需要一个接口，如果key相同的还有数据，那么就取出，如果下一个key不同了，就返回空
     */
    RowValues getNextDuplicateValueRowData() throws RuntimeException;

    /**
     * 批量取数据的接口,返回是map,所以会有一次hash的开销 不会导致指针发生变动。 会将有相同数据的值全部取出,[按照给定keys的顺序返回]
     * 比如一个索引， [0->0, 0->1 , 0->2...]
     * 那么当mget(0)的时候，应该返回[1],[2]...所有与0相关的值，但这个id是否排序，要看下层实现是否排序。
     * 如果有未找到的值，那么会向Map中插入空。
     *
     * @param keyRecordList
     * @param keyFilterOrValueFilter 为true使用keyFilter，为false使用valueFilter
     */
    Map<Record, DuplicateValueRowDataLinkedList> mgetRecordToDuplicateValueRowDataLinkedListMap(List<Record> keyRecordList, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException;

    /**
     * 批量取数据的接口，返回是list,少了一次hash的开销 不会导致指针发生变动。 会将有相同数据的值全部取出,[按照给定keys的顺序返回]
     * 比如一个索引， [0->0, 0->1 , 0->2...]
     * 那么当mget(0)的时候，应该返回[1],[2]...所有与0相关的值，但这个id是否排序，要看下层实现是否排序。
     * 如果有未找到的值，那么会向List中插入空。
     *
     * @param keyRecordList
     * @param keyFilterOrValueFilter 为true使用keyFilter，为false使用valueFilter
     */
    List<DuplicateValueRowDataLinkedList> mgetDuplicateValueRowDataLinkedListList(List<Record> keyRecordList, boolean prefixMatch, boolean keyFilterOrValueFilter) throws RuntimeException;

    //

    /**
     * 用于输出带缩进的字符串
     */
    String toStringWithInden(int inden);

}
